package name.sraynal.coodiary.file.creator;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import name.sraynal.coodiary.storage.Quote;

public class TextOutputCreator implements IOutputCreator {

	private static final int TXT_FILE_MAX_LINES = 39;
	private List<Date> dates;
	private List<Quote> quotes;
	private File outputDir;

	public void createOutput(File outputDir, List<Quote> _quotes) {
		int cursor = 0;
		this.quotes = _quotes;
		this.outputDir = outputDir;
		this.dates = new ArrayList<Date>();
		int fileIndex = 0;

		while (cursor < this.quotes.size() - 1) {
			List<Quote> printedQuotes = getPrintedQuotes(cursor);
			writeFile(fileIndex, printedQuotes);
			fileIndex++;
			cursor = cursor + printedQuotes.size();
		}
	}

	private void writeFile(int fileIndex, List<Quote> printedQuotes) {
		try {
			File output = new File(this.outputDir, "file" + fileIndex + ".txt");
			OutputStreamWriter osw = new OutputStreamWriter(
					new FileOutputStream(output), "Cp1252");
			BufferedWriter writer = new BufferedWriter(osw);
			Iterator<Quote> it = printedQuotes.iterator();
			Set<Date> printedDates = new HashSet<Date>();

			while (it.hasNext()) {
				Quote quote = it.next();
				if (!printedDates.contains(quote.getDate())) {
					printedDates.add(quote.getDate());
					writer.write("\r\n" + quote.getDate().toString() + " :\r\n"
							+ "----------\r\n\r\n");
				}
				writer.write(quote.getValue() + "\r\n");
			}
			writer.close();

		} catch (IOException e) {
			throw new RuntimeException("Error", e);
		}
	}

	private List<Quote> getPrintedQuotes(int cursor) {
		List<Quote> printedQuotes = null;
		int lineCount = TXT_FILE_MAX_LINES + 1;
		int printedQuotesNumber = TXT_FILE_MAX_LINES - 3;

		while (lineCount > TXT_FILE_MAX_LINES) {
			printedQuotes = rawGetPrintedQuotes(cursor, printedQuotesNumber);
			updateDates(printedQuotes);
			lineCount = this.dates.size() * 3 + printedQuotes.size();
			System.out.println(printedQuotes.size() + "quotes, "
					+ this.dates.size() + " dates," + "\nlineCount = "
					+ lineCount + ", " + "cursor = " + cursor);
			System.out
					.println("Printed quotes number = " + printedQuotesNumber);
			printedQuotesNumber -= 1;
		}
		return printedQuotes;
	}

	private void updateDates(List<Quote> printedQuotes) {
		Iterator<Quote> it = printedQuotes.iterator();

		while (it.hasNext()) {
			Date quoteDate = it.next().getDate();
			if (!this.dates.contains(quoteDate)) {
				this.dates.add(quoteDate);
			}
		}
	}

	private List<Quote> rawGetPrintedQuotes(int cursor, int printedQuotesNumber) {
		List<Quote> printedQuotes = new ArrayList<Quote>();
		if (cursor + printedQuotesNumber <= this.quotes.size()) {
			printedQuotes.addAll(this.quotes.subList(cursor, cursor
					+ printedQuotesNumber));
		} else {
			printedQuotes
					.addAll(this.quotes.subList(cursor, this.quotes.size()));
		}
		return printedQuotes;
	}
}